<?php

namespace app\admin\model\tongcheng;

use addons\tongcheng\enum\RiderBalanceKind;
use addons\tongcheng\model\BaseModel;
use think\Db;
use traits\model\SoftDelete;

class RiderBalanceModel extends BaseModel
{

    use SoftDelete;


    // 表名
    protected $name = 'tongcheng_rider_balance';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [

    ];

    public function zone()
    {
        return $this->belongsTo('Zone', 'zone_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }


    public function user()
    {
        return $this->belongsTo('app\admin\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }


    public function rider()
    {
        return $this->belongsTo('Rider', 'user_id', 'user_id', [], 'LEFT')->setEagerlyType(0);
    }

    /**
     * 获取骑手余额（不同区域同一账户）
     * @param $rider_id
     * @return RiderBalanceModel|null
     * @throws \think\exception\DbException
     */
    public static function getBalance($rider_id)
    {
        $rider = RiderModel::getById($rider_id);
        if (!$rider) {
            throw new \Exception('骑手信息不存在');
        }

        $balance = self::get([
            // 'zone_id'  => $rider['zone_id'],
            // 'rider_id' => $rider_id,
            'user_id' => $rider['user_id'],
        ]);
        if (!$balance) {
            $balance = self::create([
                'zone_id'        => $rider['zone_id'],
                'user_id'        => $rider['user_id'],
                // 'rider_id'       => $rider_id,
                'balance'        => 0,
                'total_inc'      => 0,
                'total_dec'      => 0,
                'total_withdraw' => 0,
            ]);
        }

        return $balance;
    }

    /**
     * 骑手余额增加
     * @param $rider_id
     * @param $kind
     * @param $amount
     * @param $changeable
     * @param $memo
     * @return RiderBalanceModel
     */
    public static function increment($rider_id, $kind, $amount, $changeable, $memo = '')
    {
        if ($amount <= 0) {
            return null;
        }

        if (!in_array($kind, RiderBalanceKind::INC_KINDS)) {
            throw new \Exception('不支持的骑手财务增加类型：' . $kind);
        }

        $memo = $memo ?: RiderBalanceKind::getDescription($kind);
        return Db::transaction(function () use ($rider_id, $kind, $amount, $changeable, $memo) {
            $balance = self::getBalance($rider_id);

            $before = $balance['balance'];
            $balance->setInc('balance', $amount);

            // 提现失败资金退回不计入总收入
            if ($kind == RiderBalanceKind::WITHDRAW_FAIL) {
                // 递减总提现金额
                $balance->setDec('total_withdraw', $amount);
            } else {
                // 递增总收入金额
                $balance->setInc('total_inc', $amount);
            }

            // 添加余额变动记录
            RiderBalanceLogModel::create([
                'zone_id'         => $balance['zone_id'],
                'user_id'         => $changeable['user_id'] ?? 0,
                'rider_id'        => is_numeric($rider_id) ? $rider_id : $rider_id['id'],
                'type'            => 'INC',
                'kind'            => $kind,
                'amount'          => $amount,
                'before'          => $before,
                'after'           => $balance['balance'],
                'changeable_id'   => $changeable['id'],
                'changeable_type' => get_class($changeable),
                'memo'            => $memo,
            ]);
            return $balance;
        });
    }

    /**
     * 骑手余额减少
     * @param $rider_id
     * @param $kind
     * @param $amount
     * @param $changeable
     * @param $memo
     * @return RiderBalanceModel
     */
    public static function decrement($rider_id, $kind, $amount, $changeable, $memo = '')
    {
        if ($amount <= 0) {
            return null;
        }

        if (!in_array($kind, RiderBalanceKind::DEC_KINDS)) {
            throw new \Exception('不支持的骑手财务扣减类型：' . $kind);
        }

        $balance = self::getBalance($rider_id);
        if ($balance['balance'] < $amount) {
            throw new \Exception('骑手余额不足');
        }

        $memo = $memo ?: RiderBalanceKind::getDescription($kind);
        return Db::transaction(function () use ($rider_id, $kind, $amount, $changeable, $memo, $balance) {
            $before = $balance['balance'];
            $balance->setDec('balance', $amount);

            // 提现
            if ($kind == RiderBalanceKind::WITHDRAW) {
                // 递增总提现金额
                $balance->setInc('total_withdraw', $amount);
            } else {
                // 递增总支出金额
                $balance->setInc('total_dec', $amount);
            }

            // 添加余额变动记录
            RiderBalanceLogModel::create([
                'zone_id'         => $balance['zone_id'],
                'user_id'         => $balance['user_id'],
                'rider_id'        => is_numeric($rider_id) ? $rider_id : $rider_id['id'],
                'type'            => 'DEC',
                'kind'            => $kind,
                'amount'          => $amount * -1,
                'before'          => $before,
                'after'           => $balance['balance'],
                'changeable_id'   => $changeable['id'],
                'changeable_type' => get_class($changeable),
                'memo'            => $memo,
            ]);
            return $balance;
        });
    }

    /**
     * 每日首次接单扣费
     * @param $rider
     * @param $time
     * @return array|bool|\PDOStatement|string|\think\Model|void|null
     */
    public static function decDayFirstTakeOrderDeduct($rider, $time = 0)
    {
        if ($rider['day_first_take_deduct_fee'] <= 0) {
            return null;
        }

        $time = $time ?: time();
        $date = date('Y-m-d', $time);
        $log  = RiderBalanceLogModel::where('rider_id', $rider['user_id'])
            ->where('kind', RiderBalanceKind::DAY_TAKE_ORDER)
            ->where('createtime', '>=', strtotime($date))
            ->where('createtime', '<', strtotime(date('Y-m-d', $time) . ' +1 day'))
            ->find();
        if ($log) {
            return $log;
        }

        try {
            RiderBalanceModel::decrement($rider['user_id'], RiderBalanceKind::DAY_TAKE_ORDER, $rider['day_first_take_deduct_fee'], $rider, "{$date}，每日首次接单扣费");
        } catch (\Exception $e) {
            $msg = $e->getMessage();
            if ($msg == '骑手余额不足') {
                tongcheng_fail("骑手余额不足，无法扣除每日首次接单扣费，请联系管理员");
            }
            tongcheng_fail($msg);
        }
    }
}
